home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
shutdown.lzh
/
shutdown_5.1
/
src
/
shutdown_lib
/
shutdown_library.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-02
|
5KB
|
207 lines
/*
shutdown_library.c --- simple shutdown library
This library is compatible with the shutdown library
written by Olaf Barthel (AmiNet:util/boot/Shutdown2_0.lha).
It is _NOT_ an update but a twin which is reduced to
calling the hook functions. You can use the library of your
preference. An update to the original library will be
released later (see IDEAS, more ideas are welcome).
This module is based on code from the original library
Copyright © 1992 by Olaf `Olsen' Barthel (not for commercial use)
Written by Bernhard Fastenrath (fasten@shw.com)
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/semaphores.h>
#include <utility/hooks.h>
#include <proto/exec.h>
#include <string.h>
#if defined (__GNUC__)
#include <stabs.h>
#endif
#include "shutdownbase.h"
typedef struct Hook Hook;
typedef struct TagItem TagItem;
typedef struct MinList MinList;
typedef struct Node Node;
typedef struct SignalSemaphore SignalSemaphore;
struct ExecBase *SysBase;
struct DosLibrary *DOSBase = NULL;
struct Library *UtilityBase = NULL;
struct Library *ShutdownBase;
MinList ShutdownList;
SignalSemaphore AccessLock;
SignalSemaphore ShutdownLock;
BYTE Closing = 0;
#if defined (__GNUC__)
const BYTE LibName[] = "shutdown.library";
const BYTE LibIdString[] = "$VER: shutdown.library 2.3 (10-26-95)";
const UWORD LibVersion = 2;
const UWORD LibRevision = 3;
#endif
#if defined (__GNUC__)
#define LIBRT
#define REG(regname)
#define STRUCT_MYLIB struct Library
#elif defined (__SASC_60)
#define LIBRT __saveds __asm
#define REG(regname) register __ ## regname
#define ADDTABL_1(name,arg1);
#define ADDTABL_2(name,arg1,arg2);
#define ADDTABL_3(name,arg1,arg2,arg3);
#define ADDTABL_END();
#define STRUCT_MYLIB struct MyLibrary
#endif
/*** internal functions ***/
static void
CallClientHooks (void)
{
if (ShutdownList.mlh_Head -> mln_Succ)
{
ShutdownInfo *Info, *NextInfo;
ULONG Mode;
Info = (ShutdownInfo *) ShutdownList.mlh_Head;
while (NextInfo = (ShutdownInfo *) Info -> sdi_Node.mln_Succ)
{
Mode = SD_EXIT;
CallHook (Info -> sdi_Hook, &Mode, NULL);
Info = NextInfo;
}
}
}
static void
cleanup (void)
{
if (DOSBase)
CloseLibrary ((struct Library *) DOSBase);
DOSBase = NULL;
if (UtilityBase)
CloseLibrary ((struct Library *) UtilityBase);
UtilityBase = NULL;
}
/*** library interface ***/
int LIBRT
__UserLibInit (REG(a6) STRUCT_MYLIB *libbase)
{
SysBase = *(struct ExecBase **)4;
ShutdownBase = (struct Library *) libbase;
if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
return 1;
if (!(UtilityBase = OpenLibrary ("utility.library", 37)))
{
cleanup ();
return 1;
}
InitSemaphore(&AccessLock);
InitSemaphore(&ShutdownLock);
NewList ((struct List *) &ShutdownList);
return 0; /* success */
}
void LIBRT
__UserLibCleanup (REG(a6) STRUCT_MYLIB *libbase)
{
cleanup ();
}
ADDTABL_1(LIBRexxDispatch,a0);
LONG LIBRT
LIBRexxDispatch (REG(a0) void *Message)
{
return 0;
}
ADDTABL_3(LIBAddShutdownInfoTagList,a0,a1,a2);
APTR LIBRT
LIBAddShutdownInfoTagList (REG(a0) Hook *Hook, REG(a1) STRPTR Name, REG(a2) TagItem *TagList)
{
if (!Closing)
{
if (Hook && Name && TagList)
{
ShutdownInfo *Info;
LONG Len = strlen (Name);
if (Info = (ShutdownInfo *) AllocVec (sizeof (ShutdownInfo) + Len + 1, MEMF_PUBLIC | MEMF_CLEAR))
{
ObtainSemaphore (&AccessLock);
Info -> sdi_Hook = Hook;
Info -> sdi_Name = (STRPTR)(Info + 1);
strcpy (Info -> sdi_Name, Name);
AddTail ((struct List *) &ShutdownList, (struct Node *) Info);
ReleaseSemaphore (&AccessLock);
return Info;
}
}
}
return NULL;
}
ADDTABL_1(LIBRemShutdownInfo,a0);
LONG LIBRT
LIBRemShutdownInfo (REG(a0) ShutdownInfo *Info)
{
if (!Closing && Info)
{
ShutdownInfo *node, *next;
ObtainSemaphore (&AccessLock);
node = (ShutdownInfo *) ShutdownList.mlh_Head;
while (next = (ShutdownInfo *) node -> sdi_Node.mln_Succ)
{
if (Info == (ShutdownInfo *) node)
{
Remove ((struct Node *) Info);
FreeVec (Info);
ReleaseSemaphore (&AccessLock);
return TRUE;
}
node = next;
}
ReleaseSemaphore (&AccessLock);
}
return FALSE;
}
ADDTABL_1(LIBShutdown,d0);
LONG LIBRT
LIBShutdown (REG(d0) ULONG mode)
{
if (!AttemptSemaphore (&ShutdownLock))
return FALSE;
else
{
/* mode is ignored by this library but
not by the original shutdown.libray */
CallClientHooks ();
ReleaseSemaphore (&ShutdownLock);
return TRUE;
}
return FALSE;
}
ADDTABL_END();